#include "string.h"
#include "exfuns.h"
#include "fattester.h"	
//#include "malloc.h"
#include "usart.h"
//////////////////////////////////////////////////////////////////////////////////	 

//文件学习心得 By xiaoyuan
//1.  下面的“文件类型列表” 要和filelistbox.h函数中的“文件过滤器个位功能定义”要对应一致。
//如：BIN文件排在第一位 对应的在filelistbox.h “#define FLBOX_FLT_BIN 	1<<0”
//2.FILE_TYPE_TBL[8][13]该二维数组的一级目录指的是文件大类，二级目录指的是文件小类
// exfun.h函数中的“f_typetell返回的类型定义”就是根据该二维数组生成的，生成法则便是f_typetell(uint8_t *fname)
// 函数中的(i<<4)|j语句，i指的是大类号（存储在高四位），j指的是小类号（存储在底四位）。 
// 但是exfun.h函数中的“f_typetell返回的类型定义”不知道有什么用途，好像在后面并没有用到。
//3.filelistbox.c文件中的读取并检查文件类型的位置目前为595-607。
//4.
//////////////////////////////////////////////////////////////////////////////////	 

 //文件类型列表
uint8_t*const FILE_TYPE_TBL[8][13] =
{
{"BIN"},			//BIN文件   //1<<0
{"LRC"},			//LRC文件   //1<<1
{"NES"},			//NES文件   //1<<2
{"TXT","C","H"},	//文本文件  //1<<3
{"MP1","MP2","MP3","MP4","M4A","3GP","3G2","OGG","ACC","WMA","WAV","MID","FLAC"},//音乐文件  //1<<4
{"BMP","JPG","JPEG","GIF",},//图片文件  //1<<5
{""},  //视频文件 //1<<6
{"GCODE"},  //GCODE文件//1<<7
};
///////////////////////////////公共文件区,使用malloc的时候////////////////////////////////////////////
//FATFS *fs[2];  		//逻辑磁盘工作区.	 
FIL *file;	  		//文件1
FIL *ftemp;	  		//文件2.
UINT br, bw;			//读写变量
FILINFO fileinfo;	//文件信息
DIR dir;  			//目录

uint8_t *fatbuf;			//SD卡数据缓存区


//将小写字母转为大写字母,如果是数字,则保持不变.
uint8_t char_upper(uint8_t c)
{
    if (c < 'A')return c;//数字,保持不变.
    if (c >= 'a')return c - 0x20;//变为大写.
    else return c;//大写,保持不变
}
//报告文件的类型
//fname:文件名
//返回值:0XFF,表示无法识别的文件类型编号.
//		 其他,高四位表示所属大类,低四位表示所属小类.
uint8_t f_typetell(uint8_t *fname)
{
    uint8_t tbuf[6];
    uint8_t *attr = '\0';//后缀名
    uint8_t i = 0, j;
    while (i < 250)
    {
        i++;
        if (*fname == '\0')break;//偏移到了最后了.
        fname++;
    }
    if (i == 250)return 0XFF;//错误的字符串.
    for (i = 0; i < 6; i++)//得到后缀名
    {
        fname--;
        if (*fname == '.')
        {
            fname++;
            attr = fname;
            break;
        }
    }
    strcpy((char *)tbuf, (const char*)attr);//copy
    for (i = 0; i < 5; i++)tbuf[i] = char_upper(tbuf[i]);//全部变为大写 
    for (i = 0; i < 8; i++)
    {
        for (j = 0; j < 13; j++)
        {
            if (*FILE_TYPE_TBL[i][j] == 0)break;//此组已经没有可对比的成员了.
            if (strcmp((const char *)FILE_TYPE_TBL[i][j], (const char *)tbuf) == 0)//找到了
            {
                return (i << 4) | j;
            }
        }
    }
    return 0XFF;//没找到		 			   
}

//得到磁盘剩余容量
//drv:磁盘编号("0:"/"1:")
//total:总容量	 （单位KB）
//free:剩余容量	 （单位KB）
//返回值:0,正常.其他,错误代码
uint8_t exf_getfree(uint8_t *drv, uint32_t *total, uint32_t *free)
{
    FATFS *fs1;
    uint8_t res;
    uint32_t fre_clust = 0, fre_sect = 0, tot_sect = 0;
    //得到磁盘信息及空闲簇数量
    res = (uint32_t)f_getfree((const TCHAR*)drv, (DWORD*)&fre_clust, &fs1);
    if (res == 0)
    {
        tot_sect = (fs1->n_fatent - 2)*fs1->csize;	//得到总扇区数
        fre_sect = fre_clust * fs1->csize;			//得到空闲扇区数	   
#if _MAX_SS!=512				  				//扇区大小不是512字节,则转换为512字节
        tot_sect *= fs1->ssize / 512;
        fre_sect *= fs1->ssize / 512;
#endif	  
        *total = tot_sect >> 1;	//单位为KB
        *free = fre_sect >> 1;	//单位为KB 
    }
    return res;
}


//得到路径下的文件夹
//返回值:0,路径就是个卷标号.
//    其他,文件夹名字首地址
uint8_t* exf_get_src_dname(uint8_t* dpfn)
{
    uint16_t temp = 0;
    while (*dpfn != 0)
    {
        dpfn++;
        temp++;
    }
    if (temp < 4)return 0;
    while ((*dpfn != 0x5c) && (*dpfn != 0x2f))dpfn--;	//追述到倒数第一个"\"或者"/"处 
    return ++dpfn;
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////////
